package fun.yyds.service.ai.impl;

import com.baidubce.qianfan.Qianfan;
import com.baidubce.qianfan.QianfanV2;
import com.baidubce.qianfan.core.StreamIterator;
import com.baidubce.qianfan.model.chat.v2.request.RequestV2;
import com.baidubce.qianfan.model.chat.v2.response.ResponseV2;
import com.baidubce.qianfan.model.chat.v2.response.StreamResponseV2;
import fun.yyds.entity.message.AiMsg;
import fun.yyds.service.ai.AiService;
import groovy.util.logging.Slf4j;
import groovyjarjarantlr4.v4.runtime.misc.NotNull;
import okhttp3.OkHttpClient;
import okhttp3.Response;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import okhttp3.sse.EventSources;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class AiServiceImpl extends HttpServlet implements AiService {

    @Override
    public AiMsg getAllChatMsg(AiMsg aiMsg) {
        QianfanV2 clientAll = new Qianfan("bce-v3/ALTAK-7ne2T2b8Oihsc8IhLwcVI/c2942ccca1349d2384cd897447974d43ad941895").v2();
        RequestV2 request = clientAll.chatCompletion()
                .model("ernie-3.5-8k")
                .addMessage("user", aiMsg.getUserMsg()) // 添加用户消息 (此方法可以调用多次，以实现多轮对话的消息传递)
                .temperature(0.7) // 自定义超参数
                .build(); // 发起请求

        ResponseV2 response = clientAll.chatCompletion(request);
        aiMsg.setResMsg(response.getChoices().get(0).getMessage().getContent());
        return aiMsg;
    }

    @Override
    public AiMsg getMyChatMsg(AiMsg aiMsg) {
        QianfanV2 clientMy = new Qianfan("2491620a3bc945258221e04beecc8d45", "3cfdfd72fe0744759c7d5c63e59b457d").v2();
        RequestV2 request = clientMy.chatCompletion()
                .model("ernie-3.5-8k")
                .addMessage("user", aiMsg.getUserMsg()) // 添加用户消息 (此方法可以调用多次，以实现多轮对话的消息传递)
                .temperature(0.7) // 自定义超参数
                .build(); // 发起请求

        ResponseV2 response = clientMy.chatCompletion(request);
        aiMsg.setResMsg(response.getChoices().get(0).getMessage().getContent());
        return aiMsg;
    }

    @Override
    public void getMyStreamChatMsg(String msg, HttpServletRequest req, HttpServletResponse resp) {
        QianfanV2 clientMy = new Qianfan("2491620a3bc945258221e04beecc8d45", "3cfdfd72fe0744759c7d5c63e59b457d").v2();
        resp.setContentType("text/event-stream");
        resp.setCharacterEncoding("UTF-8");
        // 这行代码设置了Cache-Control HTTP头部字段，值为no-cache。这意味着浏览器不应该缓存此响应。对于SSE来说，这是很重要的，因为我们希望实时更新数据，而不希望浏览器缓存旧的数据。
        resp.setHeader("Cache-Control", "no-cache");
        // 这行代码设置了Connection HTTP头部字段，值为keep-alive。这意味着客户端和服务器之间的TCP连接在响应完成后保持打开状态，以便后续的SSE事件可以通过同一个连接发送。这对于持续的数据流非常重要，因为它减少了建立新连接的开销。
        resp.setHeader("Connection", "keep-alive");

        RequestV2 aiRequest = clientMy.chatCompletion()
                .model("ernie-3.5-8k")
                .addMessage("user", "你好") // 添加用户消息 (此方法可以调用多次，以实现多轮对话的消息传递)
                .temperature(0.7) // 自定义超参数
                .build(); // 发起请求

        StreamIterator<StreamResponseV2> resps = clientMy.chatCompletionStream(aiRequest);
        // 处理流式响应

        try {
            // 创建一个AsyncContext对象并开启异步处理流程
            AsyncContext asyncContext = req.startAsync(req, resp);
            asyncContext.setTimeout(10 * 60 * 1000);
            PrintWriter writer = asyncContext.getResponse().getWriter();


//            FormBody formBody = new FormBody.Builder().add("message", msg).build();
//            Request request = new Request.Builder().url("http://127.0.0.1:9996/ai/my/stream/chat").post(formBody).build();
            // 使用EventSourceListener处理来自服务器的SSE事件
            EventSourceListener listener = new EventSourceListener() {
                @Override
                public void onOpen(@NotNull EventSource eventSource, @NotNull Response response) {
                    System.out.println("Connection opened.");
                }

                @Override
                public void onClosed(@NotNull EventSource eventSource) {
                    System.out.println("Connection closed.");
                    resps.forEachRemaining(s -> {
                        String content = s.getChoices().get(0).getDelta().getContent();
                        writer.write(content);
                        writer.flush();
                        asyncContext.complete();
                    });
                }

                @Override
                public void onEvent(@NotNull EventSource eventSource, @Nullable String id, @Nullable String type, @NotNull String data) {
                    try {
                        resps.forEachRemaining(s -> {
                            String content = s.getChoices().get(0).getDelta().getContent();
                            writer.write(content);
                            writer.flush();
                        });

                    } catch (Exception e) {
                        System.out.println("推送数据失败");
                    }
                }

                @Override
                public void onFailure(@NotNull EventSource eventSource, @Nullable Throwable t, @Nullable Response response) {
                    System.out.println("Connection failed." + t);

                    asyncContext.complete();
                }
            };
            OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).writeTimeout(50, TimeUnit.SECONDS).readTimeout(10, TimeUnit.MINUTES).build();
            EventSource.Factory factory = EventSources.createFactory(client);
//            factory.newEventSource(req, listener);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }


}
